package com.yupi.usercenter.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.usercenter.common.BaseResponse;
import com.yupi.usercenter.common.DeleteRequest;
import com.yupi.usercenter.common.ErrorCode;
import com.yupi.usercenter.common.ResultUtils;
import com.yupi.usercenter.exception.BusinessException;
import com.yupi.usercenter.model.domain.Team;
import com.yupi.usercenter.model.domain.TeamQuery;
import com.yupi.usercenter.model.domain.User;
import com.yupi.usercenter.model.domain.UserTeam;
import com.yupi.usercenter.model.request.*;
import com.yupi.usercenter.model.vo.TeamUserVO;
import com.yupi.usercenter.service.TeamService;
import com.yupi.usercenter.service.UserService;
import com.yupi.usercenter.service.UserTeamService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static com.yupi.usercenter.contant.UserConstant.ADMIN_ROLE;
import static com.yupi.usercenter.contant.UserConstant.USER_LOGIN_STATE;

/**
 * 队伍接口
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://yupi.icu">编程导航知识星球</a>
 */
@RestController
@RequestMapping("/team")
@CrossOrigin(origins= "http://localhost:3000",allowCredentials = "true")
@Slf4j
public class TeamController {

    @Resource
    private UserService userService;

    @Resource
    private TeamService teamService;

    @Resource
    private UserTeamService userTeamService;


    /**
     * @PostMapping("/add") 是一个Spring框架中的注解，用于将HTTP POST请求映射到特定的
     * 处理方法上。"/add" 是URL路径，客户端需要向这个路径发送POST请求.
     * */

    /**
     * 当客户端向/add路径发送POST请求时，addTeam方法会被调用，
     * @RequestBody注解告诉Spring框架将请求体中的JSON数据映射到Team对象中。
     * 然后，方法内部会执行创建用户的逻辑，并返回一个响应，表明用户是否创建成功.
     * */

    /**
     * 例如
     * */
    /**
     * public class User {
     *     private String username;
     *     private String password;
     *     // 其他用户相关的属性
     *     // getter和setter方法
     * */
    /**
     *{
     *     "username": "john",
     *     "password": "doe"
     * }
     * */
    /**
     * @PostMapping("/add")注解修饰的方法用于处理HTTP POST请求，
     * 当客户端发起一个URL路径为"/add"且请求体（request body）中携带Team对象的POST请求时，
     * 服务器将调用此方法。
     * */
    @PostMapping("/add")
    public BaseResponse<Long> addTeam(@RequestBody TeamAddRequest teamAddRequest,HttpServletRequest request){
        if (teamAddRequest==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser=userService.getLogininUser(request);
        Team team=new Team();
        log.info("Before copyProperties: {}", teamAddRequest);
        log.info("Before copyProperties: {}", teamAddRequest.toString());
        BeanUtils.copyProperties(teamAddRequest,team);
        log.info("After copyProperties: {}", team);
        long teamId=teamService.addTeam(team,loginUser);
        return ResultUtils.success(teamId);
    }
//    @PostMapping("/delete")
//    public BaseResponse<Boolean> deleteTeam(@RequestBody Long id){
//        if (id<=0) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        boolean result=teamService.removeById(id);
//        if (!result){
//            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"删除失败");
//        }
//        return ResultUtils.success(true);
//    }

    /**
     * 使用了@GetMapping注解来指定它处理GET请求，并映射到URL路径/get。
     * 方法的参数long id表示要获取的团队的ID。方法的返回值是一个自定义的响应类。
     * */
    /**
     * @GetMapping("/get")注解修饰的方法用于处理HTTP GET请求，
     * 当客户端发起一个URL路径为"/get"且携带查询参数"id"的GET请求时，服务器将调用此方法。
     * */
    @GetMapping("/get")
    public BaseResponse<Team> getTeamById(long id){
        // 如果传入的团队ID小于等于0，则抛出参数错误异常
        if (id<=0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 调用团队信息服务获取指定ID的团队实体
        Team team=teamService.getById(id);
        // 如果查询到的团队实体为空，则抛出数据不存在异常
        if (team==null){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 封装返回结果，将查询到的团队实体封装进成功响应对象中
        return ResultUtils.success(team);
    }

    @PostMapping("/update")
    public BaseResponse<Boolean> updateTeam(@RequestBody TeamUpdateRequest team, HttpServletRequest request){
        if (team==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser=userService.getLogininUser(request);
        boolean result=teamService.updateTeam(team,loginUser);
        if (!result){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"更新失败");
        }
        return ResultUtils.success(true);
    }

//    @GetMapping("/list")
//    public BaseResponse<List<Team>> listTeams(TeamQuery teamQuery){
//        // 如果查询条件为空，则抛出参数错误异常
//        if (teamQuery==null){
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        // 创建一个空的Team实体对象，并将请求参数中的查询条件复制到该对象中
//        Team team=new Team();
//        BeanUtils.copyProperties(team,teamQuery);
//        // 使用QueryWrapper构建查询条件
//        QueryWrapper<Team> queryWrapper=new QueryWrapper<>(team);
//        // 根据构建的查询条件，从团队信息服务中获取团队列表
//        List<Team> teamList=teamService.list(queryWrapper);
//        // 将查询结果封装到成功的响应对象中返回给客户端
//        return ResultUtils.success(teamList);
//    }
    @GetMapping("/list")
    public BaseResponse<List<TeamUserVO>> listTeams(TeamQuery teamQuery, HttpServletRequest request){
        // 1、查询队伍列表  如果查询条件为空，则抛出参数错误异常
        if (teamQuery==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean isAdmin=userService.isAdmin(request);
        List<TeamUserVO> teamList=teamService.listTeams(teamQuery,isAdmin);
        final List<Long> teamIdList=teamList.stream().map(TeamUserVO::getId).collect(Collectors.toList());
        //2、判断用户是否已加入队伍
        QueryWrapper<UserTeam> userTeamQueryWrapper=new QueryWrapper<>();
        try{
            User loginUser=userService.getLogininUser(request);
            userTeamQueryWrapper.eq("userId",loginUser.getId());
            userTeamQueryWrapper.in("teamId",teamIdList);
            List<UserTeam> userTeamList=userTeamService.list(userTeamQueryWrapper);
            //已加入的队伍 id 集合
            Set<Long> hasJoinTeamIdSet=userTeamList.stream().map(UserTeam::getTeamId).collect(Collectors.toSet());
            teamList.forEach(team->{
                boolean hasJoin=hasJoinTeamIdSet.contains(team.getId());
                team.setHasJoin(hasJoin);
            });
        }catch (Exception e){

        }
        // 3、查询已加入队伍的人数
        QueryWrapper<UserTeam> userTeamJoinQueryWrapper = new QueryWrapper<>();
        userTeamJoinQueryWrapper.in("teamId", teamIdList);
        List<UserTeam> userTeamList = userTeamService.list(userTeamJoinQueryWrapper);
        // 队伍 id => 加入这个队伍的用户列表
        Map<Long, List<UserTeam>> teamIdUserTeamList = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        teamList.forEach(team -> team.setHasJoinNum(teamIdUserTeamList.getOrDefault(team.getId(), new ArrayList<>()).size()));

        return ResultUtils.success(teamList);
    }

    @GetMapping("/list/page")
    public BaseResponse<Page<Team>> listPageTeams(TeamQuery teamQuery){
        // 如果查询条件为空，则抛出参数错误异常
        if (teamQuery==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 创建一个Team实体对象，并将查询条件从请求对象中复制过来
        Team team=new Team();
        BeanUtils.copyProperties(teamQuery,team);
        // 初始化分页对象，使用请求中的页码和每页大小
        Page<Team> page=new Page<>(teamQuery.getPageNum(),teamQuery.getPageSize());
        // 构建一个查询条件包装器
        QueryWrapper<Team> queryWrapper=new QueryWrapper<>(team);
        // 根据分页条件和查询条件，从团队信息服务中获取分页后的团队列表
        Page<Team> resultPage=teamService.page(page,queryWrapper);
        // 将分页查询结果封装到一个表示成功的响应对象中返回给前端
        return ResultUtils.success(resultPage);
    }

    /**
     * 加入队伍
     * @Param teamJoinRequest
     * @Param request
     * @return
     * */
    @PostMapping("/join")
    public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest, HttpServletRequest request){
        if (teamJoinRequest==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser=userService.getLogininUser(request);
        boolean result=teamService.joinTeam(teamJoinRequest,loginUser);
        return ResultUtils.success(result);
    }
    /**
     * 退出队伍
     * @param teamQuitRequest
     * @param request
     * @return
     * */
    @PostMapping("/quit")
    public BaseResponse<Boolean> quitTeam(@RequestBody TeamQuitRequest teamQuitRequest,HttpServletRequest request){
        if (teamQuitRequest==null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser=userService.getLogininUser(request);
        boolean result=teamService.quitTeam(teamQuitRequest,loginUser);
        return ResultUtils.success(result);
    }
    /**
     * 解散队伍
     * @param
     * @return
     * */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteTeam(@RequestBody DeleteRequest deleteRequest,HttpServletRequest request){
        if (deleteRequest==null || deleteRequest.getId()<=0){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        long id =deleteRequest.getId();
        User loginUser=userService.getLogininUser(request);
        boolean result=teamService.deleteTeam(id,loginUser);
        if (!result){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"删除失败");
        }
        return ResultUtils.success(true);
    }

    /**
     * 获取我创建的队伍
     * */
    @GetMapping("/list/my/create")
    public BaseResponse<List<TeamUserVO>> listMyCreateTeams(TeamQuery teamQuery,HttpServletRequest request){
//        if (teamQuery == null){
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        User logininUser=userService.getLogininUser(request);
//        teamQuery.setUserId(logininUser.getId());
//        List<TeamUserVO> teamList=teamService.listTeams(teamQuery,true);
//        return ResultUtils.success(teamList);


        if (teamQuery == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User logininUser=userService.getLogininUser(request);
        teamQuery.setUserId(logininUser.getId());
        List<UserTeam> userTeamList = userTeamService.list();

        // 取出不重复队伍的 ID
        Map<Long, List<UserTeam>> listMap = userTeamList.stream()
                .collect(Collectors.groupingBy(UserTeam::getTeamId));

        List<Long> idList = new ArrayList<>(listMap.keySet());
        teamQuery.setIdList(idList);
        // 计算每个队伍的成员数量
        Map<Long, Integer> teamMemberCount = userTeamList.stream()
                .collect(Collectors.groupingBy(UserTeam::getTeamId, Collectors.summingInt(c -> 1)));
        List<TeamUserVO> teamList=teamService.listTeams(teamQuery,true);

        // 更新 hasJoinNum 和 hasJoin
        for (TeamUserVO team : teamList) {
            Long teamId = team.getId(); // 假设 TeamUserVO 中有 getId() 方法
            team.setHasJoinNum(teamMemberCount.getOrDefault(teamId, 0));
            team.setHasJoin(true);
        }

        return ResultUtils.success(teamList);

    }

    /**
     * 获取我加入的队伍
     * */
    @GetMapping("/list/my/join")
    public BaseResponse<List<TeamUserVO>> listMyJoinTeams(TeamQuery teamQuery,HttpServletRequest request){
//        if (teamQuery == null){
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        User logininUser=userService.getLogininUser(request);
//        QueryWrapper<UserTeam> queryWrapper=new QueryWrapper<>();
//        queryWrapper.eq("userId",logininUser.getId());
//        List<UserTeam> userTeamList=userTeamService.list(queryWrapper);
//        //取出不重复队伍的 ID
//        Map<Long,List<UserTeam>> listMap=userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
//        List<Long> idList=new ArrayList<>(listMap.keySet());
//        teamQuery.setIdList(idList);
//        List<TeamUserVO> teamList=teamService.listTeams(teamQuery,true);
//        return ResultUtils.success(teamList);



        if (teamQuery == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        User loginUser = userService.getLogininUser(request);
        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", loginUser.getId());
        List<UserTeam> userTeamList = userTeamService.list();

        // 取出不重复队伍的 ID
        Map<Long, List<UserTeam>> listMap = userTeamList.stream()
                .collect(Collectors.groupingBy(UserTeam::getTeamId));

        List<Long> idList = new ArrayList<>(listMap.keySet());
        teamQuery.setIdList(idList);

        // 计算每个队伍的成员数量
        Map<Long, Integer> teamMemberCount = userTeamList.stream()
                .collect(Collectors.groupingBy(UserTeam::getTeamId, Collectors.summingInt(c -> 1)));

        // 获取用户已加入的队伍列表
        List<TeamUserVO> teamList = teamService.listTeams(teamQuery, true);

        // 更新 hasJoinNum 和 hasJoin
        for (TeamUserVO team : teamList) {
            Long teamId = team.getId(); // 假设 TeamUserVO 中有 getId() 方法
            team.setHasJoinNum(teamMemberCount.getOrDefault(teamId, 0));
            team.setHasJoin(true);
        }

        return ResultUtils.success(teamList);


    }

}
